using System;
using System.Collections.Generic;
using System.Text;

using Microsoft.Xna.Framework;
using CreamX.Common;
using CreamX.Framework.Attributes;




namespace CreamX.Framework.Game.Components
{
    [CreamXComponentAttribute("CreamXCollisionComponent")]
    public class CreamXCollisionComponent:CreamXComponent
    {
        #region Private Variables
        private bool _responseEnabled=true;
        private List<CreamXCollisionData> _collisions = new List<CreamXCollisionData>();
        private CollisionType _collisionType = CollisionType.Circle;
        private bool _hasCollisions;
        private List<CreamXCollisionData> cols = new List<CreamXCollisionData>();
        #endregion

        public OnCollisionDelegate OnCollision;
        private List<uint> _ignoreTypes=new List<uint>();

        public List<uint> IgnoreTypes
        {
            get { return _ignoreTypes; }
            set { _ignoreTypes = value; }
        }
        static CreamXCollisionComponent()
        {

        }
        
        public CreamXCollisionComponent()
        {
            OnCollision = new OnCollisionDelegate(OnCollisionMethod);
        }

        [CreamXComponentProperty("ResponseEnabled")]
        public bool ResponseEnabled
        {
            get { return _responseEnabled; }
            set { _responseEnabled = value; }
        }

        [CreamXComponentPropertyAttribute("CollisionType")]
        public CollisionType CollisionType
        {
            get { return _collisionType; }
            set { _collisionType = value; }
        }
        
        public SceneCollisionBody CollisionBody;

        public void OnCollisionMethod(CreamXObject ourObject, CreamXObject theirObject, ref bool discardresponse)
        {

        }
        
        public override void OnRegister()
        {
            Enabled = true;
            switch (CollisionType)
            {
                case CollisionType.Circle:
                    CollisionBody = new CircleCollisionBody(SceneObject);
                    break;
                case CollisionType.Tile:
                    CollisionBody = new TileCollisionBody(SceneObject);
                    break;
                case CollisionType.Square:
                    SceneObject.ResetBoundingBox();
                    CollisionBody = new RectangleCollisionBody(SceneObject);
                    break;
            }
            base.OnRegister();
        }
        
        public bool HasCollisions
        {
            get { return _hasCollisions; }
            set { _hasCollisions = value; }
        }

        public override void Update(float elapsed)
        {
            _hasCollisions = false;
            base.Update(elapsed);
        }
        
        public void TryMove(ref float time,ref Vector2 velocity,List<CreamXCollisionData> collisions)
        {
            if (Enabled)
            {
                List<CreamXObject> _objects = SceneObject.Scene.Objects;
                foreach (CreamXObject cxo in _objects)
                {
                    if (cxo == SceneObject)
                        continue;
                    //cols.Clear();
                    if (cxo.GetComponent<CreamXCollisionComponent>() != null)
                    {
                        
                        CollisionBody.TestMove(time, velocity, collisions,cxo);
                        CollisionType colty = cxo.GetComponent<CreamXCollisionComponent>().CollisionType;
                        if (collisions.Count > 0)
                        {
                            _hasCollisions = true;
                        }
                    }
                }
            }
            bool disc = false;
            foreach (CreamXCollisionData oj in collisions)
            {
                if (OnCollision != null)
                    OnCollision(SceneObject, oj.SceneObject, ref disc);
                CreamXCollisionComponent coli = oj.SceneObject.GetComponent<CreamXCollisionComponent>();
                if (coli != null &&
                    coli.OnCollision != null)
                    coli.OnCollision(oj.SceneObject, SceneObject, ref disc);
            } 
        }
    }
   
    public delegate void OnCollisionDelegate(CreamXObject creamxobject,CreamXObject theirObject,ref bool discardResponse);
    
    
  
    

    
}
